﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.instructions.common
{
    class ByteCodeReader
    {
        public byte[] code;
        public int pc;

        public void Reset(byte[] code, int pc)
        {
            this.code = code;
            this.pc = pc;
        }

        public byte ReadUint8()
        {
            return code[pc++];
        }

        public byte[] ReadBytes(uint length)
        {
            byte[] result = new byte[length];
            for (uint i = 0; i < length; i++)
            {
                result[i] = ReadUint8();
            }
            return result;
        }

        public sbyte ReadInt8()
        {
            return (sbyte)(ReadUint8());
        }

        public short ReadInt16()
        {
            byte[] temp = ReadBytes(2);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(temp);
            return BitConverter.ToInt16(temp, 0);
        }
        public ushort ReadUint16()
        {
            byte[] temp = ReadBytes(2);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(temp);
            return BitConverter.ToUInt16(temp, 0);
        }

        public int ReadInt32()
        {
            byte[] temp = ReadBytes(4);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(temp);
            return BitConverter.ToInt32(temp, 0);
        }

        // used by lookupswitch and tableswitch
        public int[] ReadInt32s(int length)
        {
            int[] result = new int[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = ReadInt32();
            }
            return result;
        }

        // used by lookupswitch and tableswitch
        public void SkipPadding()
        {
            while (pc % 4 != 0)
            {
                ReadUint8();
            }
        }
    }
}
